package cn.tnar.yunpark.puxd;

import cn.tnar.yunpark.model.SpaceStatus;
import cn.tnar.yunpark.service.SensorEventDispatcher;
import cn.tnar.yunpark.util.RC4Util;
import cn.tnar.yunpark.util.Strings;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 普信达地磁上传接口
 * Created by tieh on 2016/11/3.
 */
@RestController
@RequestMapping("puxd")
public class ParkingDataController {

    public static final Logger log = LoggerFactory.getLogger(ParkingDataController.class);

    private static final int SUCCESS = 200;
    private static final int ERR_SIGN = 201;
    private static final int ERR_PROCESS = 202;
    private static final int ERR_DUPLICATE = 203;

    private static final DateFormat TIME_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");

    private static ExecutorService pool = Executors.newFixedThreadPool(3);

    @Autowired
    SensorEventDispatcher dispatcher;

    @Value("${tnar.puxd.pwd}")
    String pwd;

    @Value("${tnar.puxd.sign-enable}")
    boolean signEnable = false;

    @Value("${tnar.puxd.rc4Key}")
    String rc4Key;

    @Value("${tnar.puxd.signKey}")
    String signKey;

    Gson mGson = new GsonBuilder().setDateFormat("yyyyMMddHHmmss").create();

    @PostMapping("ParkingDataUpload.do")
    public PuxdResponse upload(@RequestParam(name = "commandCode", required = false) String cmdCode,
                               @RequestBody PuxdRequest request) {
        PuxdResponse rsp = new PuxdResponse();
        PuxdRspData rspData = new PuxdRspData();
        try {
            if("REPORT_PARKING_DATA".equals(request.getCommand())) {
                String encodedReqData = request.getBiz_content();
                String jsonReqData = RC4Util.DecryRC4(encodedReqData, rc4Key);
                PuxdReqData reqData = mGson.fromJson(jsonReqData, PuxdReqData.class);
                upload(reqData);
            } else if("REPORT_HEART_BEAT".equals(request.getCommand())) {
                log.debug("PUXD heart beat <=");
                rsp.setCommand("REPORT_HEART_BEAT_RETURN");
            } else {
                return null;
            }
            rspData.setResultCode(SUCCESS);
            rspData.setResultMSG("OK");
        } catch (JsonSyntaxException e) {
            log.error("parse PUXD json error", e);
            rspData.setResultCode(ERR_PROCESS);
            rspData.setResultMSG("JSON数据格式错误");
        } catch (PuxdException e) {
            log.warn(e.getMessage());
            rspData.setResultCode(ERR_PROCESS);
            rspData.setResultMSG(e.getMessage());
        } catch (Exception e) {
            log.error("upload PUXD data error", e);
            rspData.setResultCode(ERR_PROCESS);
            rspData.setResultMSG("接口异常");
        }

        String jsonRspData = mGson.toJson(rspData);
        String encodedRspData = RC4Util.EncryRC4(jsonRspData, rc4Key);
        String sign = SignatureChecker.sign(jsonRspData, signKey);

        rsp.setMessage_id(request.getMessage_id());
        rsp.setSign(sign);
        rsp.setTimestamp(TIME_FORMAT.format(new Date()));
        rsp.setBiz_content(encodedRspData);
        return rsp;
    }

    private void upload(PuxdReqData reqData) throws PuxdException {
        String bayId = Strings.nullToEmpty(reqData.getCMCID(), reqData.getPMDID());
        if (Strings.isNullOrEmpty(bayId)) {
            throw new PuxdException("CMCID+PMDID不能为空");
        }

        String datetime = reqData.getParkingDate();
        try {
            TIME_FORMAT.parse(datetime);
        } catch (ParseException e) {
            throw new PuxdException("parkingDate格式不正确");
        } catch (NullPointerException e) {
            throw new PuxdException("parkingDate不能为空");
        }

        dispatcher.dispatch(new SpaceStatus(bayId, PuxdUtil.toLbmStatus(reqData.getParkingState()), datetime));
    }
}
